package internal

import (
	"devops-server/global"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"time"
)

type _zap struct{}

var Zap = new(_zap)

// 定义日志输出时间格式
func (z *_zap) CustomTimeEncoder(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
	encoder.AppendString(global.Config.Zap.Prefix + t.Format("2006/01/02 - 15:04:05.000"))
}

func (z *_zap) GetEncoderConfig() zapcore.EncoderConfig {
	// 返回一个 zapcore.EncoderConfig 实例，该实例已经根据需求配置好了各个字段
	return zapcore.EncoderConfig{
		MessageKey:     "message",                          // 日志信息内容的键名
		LevelKey:       "level",                            // 日志级别的键名
		TimeKey:        "time",                             // 日志输出时间的键名
		NameKey:        "logger",                           // 日志名称的键名
		CallerKey:      "caller",                           // 调用者的键名
		StacktraceKey:  global.Config.Zap.StacktraceKey,    // 堆栈信息的键名，从全局配置中获取
		LineEnding:     zapcore.DefaultLineEnding,          // 日志行的结束符，使用默认值
		EncodeLevel:    global.Config.Zap.ZapEncodeLevel(), // 日志级别的编码器，从全局配置中获取编码器函数
		EncodeTime:     z.CustomTimeEncoder,                // 自定义的时间编码器
		EncodeDuration: zapcore.SecondsDurationEncoder,     // 持续时间的编码器，使用秒为单位
		EncodeCaller:   zapcore.FullCallerEncoder,          // 调用者的编码器，使用完整格式
	}
}

// 获取日志编码器，根据配置的日志格式返回不同的编码器和终端
func (z *_zap) GetEncoder() zapcore.Encoder {
	if global.Config.Zap.Format == "json" {
		return zapcore.NewJSONEncoder(z.GetEncoderConfig())
	}
	return zapcore.NewConsoleEncoder(z.GetEncoderConfig())
}

// 获取日志核心，根据配置的日志级别返回不同的日志核心
func (z *_zap) GetEncodeCore(l zapcore.Level, level zap.LevelEnablerFunc) zapcore.Core {
	// 使用lumberjack进行日志切割
	writer := LumberjackLogs.GetWriteSyncer(l.String())
	return zapcore.NewCore(z.GetEncoder(), writer, level)
}

func (z *_zap) GetLevelPriority(level zapcore.Level) zap.LevelEnablerFunc {
	switch level {
	case zapcore.DebugLevel:
		return func(level zapcore.Level) bool { // 调试级别
			return level == zapcore.DebugLevel
		}
	case zapcore.InfoLevel:
		return func(level zapcore.Level) bool { // 日志级别
			return level == zapcore.InfoLevel
		}
	case zapcore.WarnLevel:
		return func(level zapcore.Level) bool { // 警告级别
			return level == zapcore.WarnLevel
		}
	case zapcore.ErrorLevel:
		return func(level zapcore.Level) bool { // 错误级别
			return level == zapcore.ErrorLevel
		}
	case zapcore.DPanicLevel:
		return func(level zapcore.Level) bool { // 严重错误级别
			return level == zapcore.DPanicLevel
		}
	case zapcore.PanicLevel:
		return func(level zapcore.Level) bool { // 致命错误级别
			return level == zapcore.PanicLevel
		}
	case zapcore.FatalLevel:
		return func(level zapcore.Level) bool { // 终止错误级别
			return level == zapcore.FatalLevel

		}
	default:
		return func(level zapcore.Level) bool { // 调试级别
			return level == zapcore.InfoLevel
		}
	}
}

// 根据配置文件的Level获取[]Zapcore.Core
func (z *_zap) GetZapCores() []zapcore.Core {
	cores := make([]zapcore.Core, 0, 7)
	for level := global.Config.Zap.TransportLevel(); level <= zapcore.FatalLevel; level++ {
		cores = append(cores, z.GetEncodeCore(level, z.GetLevelPriority(level)))
	}
	return cores
}
